package com.xyht.sca_s.student_manage_system.modules.rxRegistrationChargePayment.util;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.PrepayWithRequestPaymentResponse;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ExceptionCast;
import com.xyht.sca_s.student_manage_system.common.util.TimeUtil;
import com.xyht.sca_s.student_manage_system.modules.advanceRegistration.entity.req.RxAdvanceRegistrationStudentPaymentReq;
import com.xyht.sca_s.student_manage_system.modules.chargePayment.entity.SmsWnsChargePaymentRecord;
import com.xyht.sca_s.student_manage_system.modules.chargePayment.entity.resp.PrepayPaymentResp;
import com.xyht.sca_s.student_manage_system.modules.chargePayment.entity.resp.SmsWnsChargePaymentRecordResp;
import com.xyht.sca_s.student_manage_system.modules.payment.wxpay.entity.PrepayPaymentReq;
import com.xyht.sca_s.student_manage_system.modules.payment.wxpay.entity.WxPayFunctions;
import com.xyht.sca_s.student_manage_system.modules.payment.wxpay.util.WxPayUtil;
import com.xyht.sca_s.student_manage_system.modules.rxRegistrationChargePayment.entity.RxRegistrationChargePaymentCategoryDivide;
import com.xyht.sca_s.student_manage_system.modules.rxRegistrationChargePayment.entity.RxRegistrationChargePaymentRecord;
import com.xyht.sca_s.student_manage_system.modules.rxRegistrationChargePayment.entity.req.RxRegistrationChargePaymentCategoryDivideReq;
import com.xyht.sca_s.student_manage_system.modules.rxRegistrationChargePayment.entity.req.RxRegistrationChargePaymentRecordReq;
import com.xyht.sca_s.student_manage_system.modules.rxRegistrationChargePayment.entity.resp.RxRegistrationPrepayPaymentResp;
import com.xyht.sca_s.student_manage_system.modules.rxRegistrationChargePayment.mapper.RxRegistrationChargePaymentCategoryDivideMapper;
import com.xyht.sca_s.student_manage_system.modules.rxRegistrationChargePayment.mapper.RxRegistrationChargePaymentRecordMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.advanceRegistration.constant.IsPayConstant.IS_PAY;
import static com.xyht.sca_s.student_manage_system.modules.advanceRegistration.constant.IsPayConstant.IS_PAY_NOT;
import static com.xyht.sca_s.student_manage_system.modules.rxRegistrationChargePayment.constant.PaymentTypeConstant.*;

/**
 * 招生管理 支付工具类
 */
@Component
public class PaymentUtil {

    @Resource
    private RxRegistrationChargePaymentRecordMapper chargePaymentRecordMapper;
    @Resource
    private RxRegistrationChargePaymentCategoryDivideMapper chargePaymentCategoryDivideMapper;
    @Resource
    private WxPayUtil wxPayUtil;


    /**
     *
     * @param recordReq  收费信息
     * @return 预支付信息
     */
    @Transactional
    public RxRegistrationPrepayPaymentResp payment(RxRegistrationChargePaymentRecordReq recordReq) {
        //校验
        if (isNullOrEmpty(recordReq.getType(),recordReq.getPlanId(),recordReq.getStuId(),recordReq.getMode(),
                recordReq.getWxPayFunction(),recordReq.getOpenId(),recordReq.getWxPayFunction())) {
            return null;
        }
        // 校验各项分配金额
        List<RxRegistrationChargePaymentCategoryDivideReq> divideReqList = recordReq.getDivideReqList();
        if (divideReqList.isEmpty()) {
            return null;
        }
        String type = recordReq.getType();
        String stuId = recordReq.getStuId();
        String planId = recordReq.getPlanId();
        String openId = recordReq.getOpenId();
        Integer mode = recordReq.getMode();
        String description = null;
        switch (type) {
            case RX_REGISTRATION_CHARGE_PAYMENT_RECORD_TYPE_ADVANCE:
                description = RX_REGISTRATION_CHARGE_PAYMENT_RECORD_TYPE_DES_ADVANCE;
                break;
            case RX_REGISTRATION_CHARGE_PAYMENT_RECORD_TYPE_CONFIRM:
                description = RX_REGISTRATION_CHARGE_PAYMENT_RECORD_TYPE_DES_CONFIRM;
                break;
            case RX_REGISTRATION_CHARGE_PAYMENT_RECORD_TYPE_WELCOME:
                description = RX_REGISTRATION_CHARGE_PAYMENT_RECORD_TYPE_DES_NEW_WELCOME;
                break;
        }


        // 声明公共数据

        WxPayFunctions wxPayFunction = recordReq.getWxPayFunction(); //商户
        BigDecimal totalAmount = new BigDecimal(0); // 付款总金额
        Date timeExpire = TimeUtil.AddMinute(new Date(), 30); // 设置过期时间(订单失效时间)
        RxRegistrationChargePaymentRecord paymentRecord = new RxRegistrationChargePaymentRecord(); // 新生成的支付记录
        PrepayWithRequestPaymentResponse prepayWithRequestPaymentResponse;//构造预支付码给前端
        RxRegistrationPrepayPaymentResp prepayPaymentResp = new RxRegistrationPrepayPaymentResp();  //返回参数
        paymentRecord.setExpireTime(timeExpire);  // 设置过期时间 = 当前时间 + 30min
        paymentRecord.setType(type);
        paymentRecord.setMode(mode);
        paymentRecord.setWxOpenId(openId);
        paymentRecord.setStuId(stuId);
        paymentRecord.setPlanId(planId);
        chargePaymentRecordMapper.insert(paymentRecord);
        if (isNullOrEmpty(paymentRecord.getId())) {
            return null;
        }

        //收费项
        for (RxRegistrationChargePaymentCategoryDivideReq divideReq : divideReqList) {
            if (isNullOrEmpty(divideReq.getAmount())) {
                return null;
            }
            // 校验分配金额
            if (divideReq.getAmount().compareTo(BigDecimal.valueOf(0)) < 0 // 分配金额小于0
            ) {
                return null;
            }

            // 生成金额分配数据
            RxRegistrationChargePaymentCategoryDivide categoryDivide = new RxRegistrationChargePaymentCategoryDivide();
            BeanUtils.copyProperties(divideReq,categoryDivide);
            categoryDivide.setPaymentRecordId(paymentRecord.getId());
            categoryDivide.setPlanId(planId);
            categoryDivide.setStuId(stuId);
            categoryDivide.setAmount(divideReq.getAmount());
            chargePaymentCategoryDivideMapper.insert(categoryDivide);

            totalAmount = totalAmount.add(divideReq.getAmount());
        }

        //查该学生的缴费记录
//        List<RxRegistrationChargePaymentRecord> paymentRecordList = chargePaymentRecordMapper.selectList(new LambdaQueryWrapper<RxRegistrationChargePaymentRecord>()
//                .eq(RxRegistrationChargePaymentRecord::getType, type)
//                .eq(RxRegistrationChargePaymentRecord::getPlanId, planId)
//                .eq(RxRegistrationChargePaymentRecord::getStuId, stuId));


        // 发起支付
        PrepayPaymentReq prepayPaymentReq = new PrepayPaymentReq();
        prepayPaymentReq.setDescription(description);
        prepayPaymentReq.setOutTradeNo(paymentRecord.getId());
        prepayPaymentReq.setTimeExpire(timeExpire);
        // 设置订单金额 单位：分(订单金额 = 原金额(元) * 100)
        int total = totalAmount.multiply(BigDecimal.valueOf(100)).intValue();
        prepayPaymentReq.setTotal(total);
        prepayPaymentReq.setOpenId(openId);
        prepayPaymentReq.setNotifyUrl("rxRegistrationPayCallback");

        // 发起支付
        prepayWithRequestPaymentResponse = wxPayUtil.prepayPayment(prepayPaymentReq, wxPayFunction);

        if (prepayWithRequestPaymentResponse == null) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.WNS_PAYMENT_PRE_PAYMENT_INFO_MISSING));
        }

        // 移除无效数据(超过半小时未支付)
        List<RxRegistrationChargePaymentRecord> invalidPaymentRecordList = chargePaymentRecordMapper.selectList(new LambdaQueryWrapper<RxRegistrationChargePaymentRecord>()
                .eq(RxRegistrationChargePaymentRecord::getPlanId, recordReq.getPlanId())
                .eq(RxRegistrationChargePaymentRecord::getStuId, recordReq.getStuId())
                .le(RxRegistrationChargePaymentRecord::getExpireTime, new Date())
                .isNull(RxRegistrationChargePaymentRecord::getPaymentTime));
        if (!invalidPaymentRecordList.isEmpty()) {
            List<String> invalidPaymentRecordIdList = invalidPaymentRecordList.stream().map(RxRegistrationChargePaymentRecord::getId).distinct().collect(Collectors.toList());
            chargePaymentCategoryDivideMapper.delete(new LambdaQueryWrapper<RxRegistrationChargePaymentCategoryDivide>()
                    .in(RxRegistrationChargePaymentCategoryDivide::getPaymentRecordId, invalidPaymentRecordIdList));
            chargePaymentRecordMapper.deleteBatchIds(invalidPaymentRecordIdList);
        }

        // 设置预支付信息
        BeanUtils.copyProperties(prepayWithRequestPaymentResponse, prepayPaymentResp);
        prepayPaymentResp.setTimestamp(prepayWithRequestPaymentResponse.getTimeStamp());
        // 记录预支付数据
        paymentRecord.setPrepayId(JSON.toJSONString(prepayPaymentResp));
        paymentRecord.setConfigName(wxPayFunction.getWxPayCommonConfig().getCONFIG_NAME());
        chargePaymentRecordMapper.updateById(paymentRecord);
        prepayPaymentResp.setIsPay(IS_PAY_NOT);
        return prepayPaymentResp;

    }


}
